import { applyDecorators, createParamDecorator, ExecutionContext, SetMetadata, UseInterceptors } from '@nestjs/common'
import { EventTypes } from '../event-types.enum'
import { AnalyticsInterceptor } from '../analytics.interceptor'
import { SessionAnalytics } from '../models/session-analytics.model'
import { EventAnalytics } from '../models/event-analytics.model'
import { FastifyRequest } from 'fastify'
import { extractCfAnalytics } from '../extract-bc-analytics.function'

export const ANALYTICS_ENABLED_KEY = Symbol('AnalyticsEnabled')
export const ANALYTICS_OPTIONS_KEY = Symbol('AnalyticsOptionsInternal')

export interface AnalyticsOptionsInternal<T = any> {
  type: EventTypes
  affected?: (ctx: ExecutionContext, response: T) =>
    string | undefined | Promise<string | undefined>
  extract?: (ctx: ExecutionContext, response: T) =>
    Record<string, any> | undefined | Promise<Record<string, any> | undefined>
  user?: (ctx: ExecutionContext, response: T) =>
    string | undefined | Promise<string | undefined>
}

export type AnalyticsOptions = Omit<AnalyticsOptionsInternal, 'type'>

export const AnalyseRequest = (
  event: EventTypes,
  options?: AnalyticsOptions,
) => {
  return applyDecorators(
    SetMetadata(ANALYTICS_ENABLED_KEY, true),
    SetMetadata(ANALYTICS_OPTIONS_KEY, { type: event, ...options }),
    UseInterceptors(AnalyticsInterceptor),
  )
}

export const RequestSession = createParamDecorator((data: any, ctx: ExecutionContext) => {
  return ctx.switchToHttp().getRequest<{ session: SessionAnalytics }>().session
})

export const RequestEvent = createParamDecorator((data: any, ctx: ExecutionContext) => {
  return ctx.switchToHttp().getRequest<{ event: EventAnalytics }>().event
})

export const RequestCf = createParamDecorator((data: any, ctx: ExecutionContext) => {
  return extractCfAnalytics(ctx.switchToHttp().getRequest<FastifyRequest>().headers, process.env.CF_ANALYTICS_SECRET)
})